package com.icinfo.cloud.provider.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.icinfo.cloud.provider.common.constant.Constant;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author lxj
 * @date 2022/2/17
 **/
public class BaseUtil {


    /***
     * 生成uid
     * @author lxj
     * @date  2022/2/17
     * @return  String
     **/
    public static String createUid(){
        return UUID.randomUUID().toString().replace("-","");
    }


    /***
     * 字符时间转为日期
     * @author lxj
     * @date  2022/2/18
     * @param  str     入参时间
     * @return Date
     **/
    public static LocalDateTime stringToLocalDateTime(String str){
        if(StringUtils.isEmpty(str)){
            return null;
        }
        System.out.println(str.length());
        if(str.trim().length()<11){
            str = str +" 00:00:00";
        }else if(str.trim().length()<17){
            str = str +":01";
        }
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        try {
            LocalDateTime time =  LocalDateTime.parse(str,fmt);
            return time;
        } catch (Exception e) {
            return null;
        }

    }

    /**
     * 描述: 获取N天后日期String
     * @auther 胡义振
     * @date 2014-10-17
     * @param date
     * @param days 天数
     * @return
     */
    public static String getAfterDateByDays(Date date,int days) {
        try	{
            Calendar now = Calendar.getInstance();
            now.setTime(date);
            now.add(Calendar.DAY_OF_YEAR,days);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return sdf.format(now.getTime());
        }catch(Exception er) {
            return null;
        }
    }
    /**
     * 描述: 获取N天后日期Timestamp
     * @auther 胡义振
     * @date 2014-10-17
     * @param date
     * @param days 天数
     * @return
     */
    public static Timestamp getTimeStampAfterDateByDays(Date date, int days) {
        try	{
            Calendar now = Calendar.getInstance();
            now.setTime(date);
            now.add(Calendar.DAY_OF_YEAR,days);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String str =  sdf.format(now.getTime());
            return Timestamp.valueOf(str);
        }catch(Exception er) {
            return null;
        }
    }

    /**
     * 身份证规则校验
     *
     * @author  lxj
     */
    public static boolean isRightIdNo(String idNo){
        if (StringUtils.isEmpty(idNo)) {
            return false;
        }
        idNo = idNo.replaceAll("x","X");
        if(idNo.length() == 15){
            //第一代身份证正则表达式(15位)
            String isIDCard1 = "^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$";
            return idNo.matches(isIDCard1);
        }else if(idNo.length() == 18){
            //第二代身份证正则表达式(18位)
            String isIDCard2 ="^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])((\\d{4})|\\d{3}[A-Z])$";
            //验证身份证
            if (!idNo.matches(isIDCard2)) {
                return false;
            }else {
                //校验最后一位校验码
                int[] array = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
                int count = 0;
                for(int i= 0;i<idNo.length();i++){
                    if(i == 17) {
                        break;
                    }
                    String temp = Character.toString(idNo.charAt(i));
                    count += Integer.parseInt(temp) * array[i];
                }
                int remain = count % 11;
                String last = null;
                switch (remain){
                    case 0 : last = "1";break;
                    case 1 : last = "0";break;
                    case 2 : last = "X";break;
                    case 3 : last = "9";break;
                    case 4 : last = "8";break;
                    case 5 : last = "7";break;
                    case 6 : last = "6";break;
                    case 7 : last = "5";break;
                    case 8 : last = "4";break;
                    case 9 : last = "3";break;
                    case 10 : last = "2";break;
                    default:last="";
                }
                return Character.toString(idNo.charAt(17)).equals(last);
            }
        }else {
            //身份证既不是18位也不是15位
            return false;
        }
    }

    public static String sendGETRequest(String path, Map<String, String> params){
        InputStream inputStream = null;
        HttpURLConnection conn = null;
        try {
            StringBuilder url = new StringBuilder (path);
            url.append ("?");
            for ( Map.Entry<String, String> entry : params.entrySet () ) {
                url.append (entry.getKey ()).append ("=");
                url.append (URLEncoder.encode (entry.getValue (), "UTF-8"));
                url.append ("&");
            }
            conn = (HttpURLConnection) new URL(url.toString ()).openConnection ();
            conn.setConnectTimeout (5000);
            conn.setRequestMethod ("GET");
            if (conn.getResponseCode () == 200) {
                inputStream = conn.getInputStream ();
                byte[] dateStream = readStream (inputStream);
                return new String (dateStream);
            }
        } catch (Exception e) {
            e.printStackTrace ();
        } finally {
            if (conn != null) {
                conn.disconnect ();
            }
        }
        return null;
    }

    /**
     * 读取流
     * @param inStream
     * @return 字节数组
     * @throws Exception
     */
    public static byte[] readStream(InputStream inStream) throws Exception{
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream ();
        byte[] buffer = new byte[2048];
        int len = -1;
        while ((len = inStream.read (buffer)) != -1) {
            outSteam.write (buffer, 0, len);
        }
        outSteam.close ();
        inStream.close ();
        return outSteam.toByteArray ();
    }

    public static String post(String url, JSONObject reqJson) {
        String result = null;
        CloseableHttpResponse response = null;
        try(
            CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpEntityEnclosingRequestBase requestBase = new HttpPost(url);

            // 请求
            StringEntity entity = new StringEntity(reqJson.toJSONString(),"utf-8");
            entity.setContentEncoding("utf-8");
            entity.setContentType(ContentType.APPLICATION_JSON.getMimeType());
            requestBase.setEntity(entity);

            // 发送给请求
            response =  httpClient.execute(requestBase);
            // 获取返回值
            result = EntityUtils.toString(response.getEntity(), "utf-8");
            if (response != null) {
                response.close();
            }
            httpClient.close();
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return result;
        }
    }

    /**
     * 实名认证---姓名+身份证校验
     * @author lxj
     * @date  2022/2/26
     * @param realName 姓名, certNo 身份证
     * @return boolean
     **/
    /*public static boolean checkRealName( String realName,String idCard){
        try {
            JSONObject json = new JSONObject();
            json.put("idCard",idCard);
            json.put("realName",realName);
            json.put("secretkey",Md5Util.md5(Constant.REAL_NAME_CHECK_SECRET+idCard));
            String ret =  post(Constant.REAL_NAME_CHECK_URL,json);
            System.out.println("----------------"+ret);
            JSONObject retJson = JSONObject.parseObject(ret);
            if(retJson.getString("status").equals("success")){
                JSONObject js = retJson.getJSONObject("data");
                if(StringUtils.isBlank(js.getString("shenfzbs"))||Constant.STRING_1.equals(js.getString("shenfzbs"))){
                    return true;
                }
            }
        } catch (Exception e) {
            System.out.println("实名认证错误了："+e.getMessage());
        }
        return false;
    }*/

    /**
     * 描述: 计算两日期相差天数
     * @auther lxj
     * @date 2022-02-27
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return
     */
    public static int getBetweenDays(Date startDate,Date endDate) {
        try	{
            Calendar startCalendar = Calendar.getInstance();
            startCalendar.setTime(startDate);
            long startTime = startCalendar.getTimeInMillis();
            Calendar endCalendar = Calendar.getInstance();
            endCalendar.setTime(endDate);
            long endTime = endCalendar.getTimeInMillis();
            long between_days = (endTime-startTime)/(1000*60*60*24);
            return Integer.parseInt(String.valueOf(between_days));
        }catch(Exception er){
            return 0;
        }
    }

    /**
     * 描述: 字符串转为日期类型--当天开始时间
     * @auther lxj
     * @return
     */
    public static Date getTodayStartDate(){
        try{
            SimpleDateFormat sdf = new SimpleDateFormat(Constant.DATE_FORMAT);
            return sdf.parse(LocalDate.now()+" 00:00:00");
        }catch (Exception er){
            return null;
        }
    }
    /**
     * 描述: 字符串转为日期类型--当天结束时间
     * @auther lxj
     * @return
     */
    public static Date getTodayEndDate(){
        try{
            SimpleDateFormat sd = new SimpleDateFormat(Constant.TIME_FORMAT);
            return sd.parse(LocalDate.now()+" 23:59:59");
        }catch (Exception er){
            return null;
        }
    }


    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static HashMap<String, Object> javaToMap(Object javaBean) {
        HashMap<String,Object> map = new HashMap<>();
        try {
            // 获取javaBean属性
            BeanInfo beanInfo = Introspector.getBeanInfo(javaBean.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            if (propertyDescriptors != null && propertyDescriptors.length > 0) {
                String propertyName = null; // javaBean属性名
                Object propertyValue = null; // javaBean属性值
                for (PropertyDescriptor pd : propertyDescriptors) {
                    propertyName = pd.getName();
                    if (!propertyName.equals("class")) {
                        Method readMethod = pd.getReadMethod();
                        propertyValue = readMethod.invoke(javaBean, new Object[0]);
                        map.put(propertyName, propertyValue);
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 获取当日  ==yyyy年MM月dd日
     * @return
     */
    public static String getNowDate(){
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy年MM月dd日");
        String now = fmt.format(new Date());
        return now;
    }

    /**
     * 获取当日  ==yyyy年MM月dd日 MM时mm分
     * @return
     */
    public static String getNowDateTime(){
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分");
        String now = fmt.format(new Date());
        return now;
    }


    /**
     * 描述：生成指定位数的随机数
     *
     * @param length 随机数长度
     * @return 指定长度随机数
     * @author xiangyuyu
     * @date 2022-03-12 19:30
     */
    public static String getRandom(int length) {
        StringBuilder val = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            val.append(random.nextInt(10));
        }
        return val.toString();
    }


    /*
     * 把日期类型字符串 格式化 年月日
     */
    public static String getFormatDate(String str) {

        SimpleDateFormat fmt = null;
        Date data = null;
        try {
            fmt = new SimpleDateFormat("yyyy-MM-dd");
            data = fmt.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
            return "";
        }
        fmt = new SimpleDateFormat("yyyy年MM月dd日");
        return fmt.format(data);
    }
    /*
     * 把日期类型字符串 格式化 年月日 时分
     */
    public static String getFormatDateTime(String str) {

        SimpleDateFormat fmt = null;
        Date data = null;
        try {
            fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            data = fmt.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
            return "";
        }
        fmt = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分");
        return fmt.format(data);
    }

    /**
     * LocalDateTime 转date
     * @param time
     * @return
     */
    public static Date localDateToDate(LocalDateTime time){
        //构建Instant对象并设置时区
        Instant instant = time.toInstant(ZoneOffset.of("+8"));
        Date date = Date.from(instant);
        return date;

    }

    /**
     * LocalDateTime 转String
     * @param time
     * @return
     */
    public static String localDateTimeToStr(LocalDateTime time) {
        if (time == null) {
            return "";
        }
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return dtf.format(time);
    }

    /**
     * LocalDateTime 转String
     * @param time
     * @return
     */
    public static String localDateTimeToFormatStr(LocalDateTime time) {
        if (time == null) {
            return "";
        }
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时:mm分");
        return dtf.format(time);
    }

    /**
     * 两个时间 间隔中文描述
     *
     * @param lastNodeAuditDate
     * @param preFlag
     * @return
     */
    public static String calTime(Date lastNodeAuditDate, Date date, String preFlag) {
        String costTime = "";
        Long seconds = (date.getTime() - lastNodeAuditDate.getTime()) / 1000;
        String flag = "剩";
        if (seconds < 0) {
            seconds = (-seconds);
            flag = "超";
        }
        int days = (int) (seconds / 60 / 60 / 24);
        //不足一天的小时
        int hours = 0;
        // 不足一小时分钟
        int minutes = 0;
        if (days == 1) {
            costTime = days + "天";
        }
        if (days > 1) {
            seconds = seconds - 60 * 60 * 24 * days;
            hours = (int) (seconds / 60 / 60);
            seconds = seconds - 60 * 60 * hours;
            minutes = (int) (seconds / 60);
            costTime = costTime + days + "天" + hours + "时" + minutes + "分";
        }
        if (days < 1) {
            hours = (int) (seconds / 60 / 60);
            if (hours > 1) {
                seconds = seconds - 60 * 60 * hours;
                minutes = (int) (seconds / 60);
                costTime = hours + "时" + minutes + "分";
            } else {
                minutes = (int) (seconds / 60);
                costTime = minutes + "分";
            }
        }
        if (com.icinfo.framework.tools.utils.StringUtils.isNotBlank(preFlag)) {
            costTime = flag + costTime;
        }
        return costTime;
    }

    /**
     * string 转 Date
     * @param str
     * @return
     */
    public static Date  stringToDate(String str){

        try {
            SimpleDateFormat fmt   = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return fmt.parse(str);
        }catch (Exception e){
            return null;
        }
    }

    /*
     * 去掉案由冗余字
     */
    public static String handleCaseReason(String caseReason){
        String signs = "的行政处罚";
        String key = "的处罚";
        String first ="对";
        if(StringUtils.isEmpty(caseReason)){
            return "";
        }else if(caseReason.endsWith(signs)){
            caseReason =  caseReason.substring(0,caseReason.indexOf(signs));
        }else if(caseReason.endsWith(key)){
            caseReason =  caseReason.substring(0,caseReason.indexOf(key));
        }
        if(caseReason.indexOf(first)>=0){
            return  caseReason.substring(caseReason.indexOf(first)+1);
        }
        return  caseReason;
    }

    public static String removeHtml(String htmlStr){
        //定义HTML标签的正则表达式
        if(StringUtils.isEmpty(htmlStr)){
            return "";
        }
        String regEx_html = "<[^>]+>";
        Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
        Matcher m_html = p_html.matcher(htmlStr);
        //去除换行
        return m_html.replaceAll("").replace("\n","");
    }

    /**
     * 描述： 指定格式将日期字符串转日期
     *
     * @author: zhengqiang
     * @date: 2022/8/31
     * @param: dateStr
     * @param: formatStr
     * @return {@link LocalDateTime}
     **/
    public static LocalDateTime stringToLocalDateTime(String dateStr, String formatStr){
        if(StringUtils.isEmpty(dateStr)){
            return null;
        }
        System.out.println(dateStr.length());
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern(formatStr);
        try {
            LocalDateTime time =  LocalDateTime.parse(dateStr, fmt);
            return time;
        } catch (Exception e) {
            return null;
        }

    }

    public static void main(String[] args) throws Exception{

        System.out.println(BaseUtil.stringToLocalDateTime("2022-04-13 19:02"));
        System.out.println(BaseUtil.handleCaseReason("对"));
        System.out.println(BaseUtil.calTime(BaseUtil.stringToDate("2022-04-13 20:02:00"),new Date(),"true"));
    }

}
